// Write C++ code here.
//
// Do not forget to dynamically load the C++ library into your application.
//
// For instance,
//
// In MainActivity.java:
//    static {
//       System.loadLibrary("profile_uart");
//    }
//
// Or, in MainActivity.kt:
//    companion object {
//      init {
//         System.loadLibrary("profile_uart")
//      }
//    }

//
// Created by Administrator on 2020/11/12.
//


#include <jni.h>
#include <string>
#include "../inc/NE10.h"
#define SAMPLES 256
extern "C"
JNIEXPORT jstring JNICALL
Java_no_nordicsemi_android_uart_view_ne101_00024Companion_stringFromJNI(JNIEnv *env, jobject thiz) {
    // TODO: implement stringFromJNI()
    std::string test;
    if(NE10_OK==ne10_init())
        test= "ne10_init succeed";
    else
        test= "ne10_init failed";
    return env->NewStringUTF(test.c_str());
}
extern "C"
JNIEXPORT jfloatArray JNICALL
Java_no_nordicsemi_android_uart_view_ne101_00024Companion_fft(JNIEnv *env, jobject thiz,jfloatArray data_in) {
    // TODO: implement fft()

    //1.获取数组指针
    ne10_float32_t *arr = env->GetFloatArrayElements(data_in, NULL);
    //2.获取数组长度
    int len=env->GetArrayLength(data_in);
    //3.fft
    jfloatArray data_out = env->NewFloatArray(len/2+1); //新建输出数组
    jfloat *arr_out =env->GetFloatArrayElements(data_out,NULL);
    ne10_float32_t src[SAMPLES] = {10};                   // A source array of input data
    ne10_fft_cpx_float32_t dst[(SAMPLES / 2) + 1] = {}; // A destination array for the transformed data
    ne10_fft_r2c_cfg_float32_t cfg;                     // An FFT "configuration structure"
    //测试数据
    //for(int i=0;i<SAMPLES;i++)
    //    arr[i]=sin(2.0*NE10_PI*i/SAMPLES)+4*sin(2.0*NE10_PI*6.0*i/SAMPLES);
    // Initialise Ne10, using hardware auto-detection to set library function pointers
    if (ne10_init() != NE10_OK)
    {
        return nullptr;
    }

    // Prepare the real-to-complex single precision floating point FFT configuration
    // structure for inputs of length `len`. (You need only generate this once for a
    // particular input size.)
    cfg = ne10_fft_alloc_r2c_float32(len);



    // Perform the FFT
    ne10_fft_r2c_1d_float32(dst, arr, cfg);
    for (int i = 0; i < (len / 2) + 1; i++)  //计算模并输出
        arr_out[i]= sqrt(dst[i].r*dst[i].r+dst[i].i*dst[i].i);



    // Free the allocated configuration structure
    ne10_fft_destroy_r2c_float32(cfg);

    //4.释放资源
    env->ReleaseFloatArrayElements(data_in,arr,0);
    env->ReleaseFloatArrayElements(data_out,arr_out,0);
    //  对于最后一个参数(如果指针指向的数组为副本时，否则该参数不起作用)
    //      0       copy back the content and free the elems buffer
    //      JNI_COMMIT      copy back the content but do not free the elems buffer
    //      JNI_ABORT       free the buffer without copying back the possible changes
    //5.返回数组
    return data_out;
}